package com.campus.secondhand.service.impl;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.campus.secondhand.common.Result;
import com.campus.secondhand.service.VerificationCodeService;

import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 验证码服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class VerificationCodeServiceImpl implements VerificationCodeService {

    private final RedisTemplate<String, Object> redisTemplate;

    // 验证码有效期（分钟）
    private static final int CODE_EXPIRE_MINUTES = 5;
    // 验证码长度
    private static final int CODE_LENGTH = 6;
    // Redis中验证码的key前缀
    private static final String CODE_PREFIX = "verification:code:";

    @Override
    public Result<Void> generateAndSendCode(String phone) {
        if (StrUtil.isBlank(phone)) {
            return Result.error(400, "手机号不能为空");
        }

        // 生成随机验证码
        String code = generateCode(CODE_LENGTH);

        // 将验证码存储到Redis中，设置过期时间
        String key = CODE_PREFIX + phone;
        redisTemplate.opsForValue().set(key, code, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);

        // TODO: 实际项目中，这里需要调用短信发送接口发送验证码到用户手机
        // 这里仅做模拟，打印日志
        log.info("向手机 {} 发送验证码: {}", phone, code);

        return Result.success(null, "验证码已发送");
    }

    @Override
    public Result<Void> generateAndSendCode(String phone, String type) {
        if (StrUtil.isBlank(phone)) {
            return Result.error(400, "手机号不能为空");
        }

        // 生成随机验证码
        String code = generateCode(CODE_LENGTH);

        // 将验证码存储到Redis中，设置过期时间
        // 如果有类型，则添加到key中
        String key = StrUtil.isBlank(type) ? CODE_PREFIX + phone : CODE_PREFIX + type + ":" + phone;
        redisTemplate.opsForValue().set(key, code, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);

        // TODO: 实际项目中，这里需要调用短信发送接口发送验证码到用户手机
        // 这里仅做模拟，打印日志
        log.info("向手机 {} 发送{}验证码: {}", phone, type == null ? "" : type, code);

        return Result.success(null, "验证码已发送");
    }

    @Override
    public boolean verifyCode(String phone, String code) {
        return verifyCode(phone, code, null);
    }

    @Override
    public boolean verifyCode(String phone, String code, String type) {
        if (StrUtil.isBlank(phone) || StrUtil.isBlank(code)) {
            return false;
        }

        // 根据是否有类型构造key
        String key = StrUtil.isBlank(type) ? CODE_PREFIX + phone : CODE_PREFIX + type + ":" + phone;
        Object savedCode = redisTemplate.opsForValue().get(key);

        if (savedCode == null) {
            return false;
        }

        // 验证码匹配成功后，删除Redis中的验证码，防止重复使用
        boolean isMatch = code.equals(savedCode.toString());
        if (isMatch) {
            redisTemplate.delete(key);
        }

        return isMatch;
    }

    /**
     * 生成指定长度的随机数字验证码
     * 
     * @param length 验证码长度
     * @return 验证码
     */
    private String generateCode(int length) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < length; i++) {
            sb.append(random.nextInt(10));
        }

        return sb.toString();
    }
}